\ There are words for true and false:

true .
false .
true hex u. decimal

\ int equality
1 1 = .

\ check if zero
1 0= .

\ less and greater
0 1 < .
0 0 < .
1 0 > .

\ is assuming unsigned value, then wrong result
-1 1 u< .
\ compare to
-1 1 < .


\ boolean words work bitwise. For example:

1 2 and .

\ Will be treated like this:

\     0000 0001 (is 1)
\ and 0000 0010 (is 2)
\  -> 0000 0000 (is 0)

\ or written in binary:

\ %00000001 %00000010 and -> %00000000

\ Here is an example for or:

1 2 or .

\    0000 0001 (is 1)
\ or 0000 0010 (is 2)
\ -> 0000 0011 (is 3)

\ boolean words can be used with flags (zero or non-zero)

\ To make a proper flag out of any integer, you can use 0<>:

3 0<> .

\ 0= checks for all bits being 0. Since false is encoded by 0, this
\ turns any non-zero into a 0 and any 0 into a -1.

3 0= .

\ Boolean words can replace conditionals:

: foo ( n1 -- n2 )
  ( if there is not a 0, then write a 14, otherwise write a 0 )
  0= if 14 else 0 then ;

: bar ( n1 -- n2 )

  \ -1 has all bits 1 and will not filter anything out when used with
  \ `and` as a bit mask, but if the other argument has a 0 bit
  \ anywhere, the result will also have a 0 bit at that position,
  \ because both bits must be 1 for the resulting bit to be 1. A 0 on
  \ the other hand will have all bits 0, filtering everything out,
  \ when used as a bit mask, resulting in a 0 as a total result.
  0= 14 and

  \ examples:

  \ 0 0= -> -1
  \ -1 14 -> -1 14
  \ -1 14 and -> 14

  \ 123 0= -> 0
  \ 0 14 -> 0 14
  \ 0 14 and -> 0
;

\ Exercise: Write min without making use of `if`.

\ Previous version of min:

: min ( n1 n2 -- n )
  \ Only let the `if` decide whether or not to swap the
  \ arguments.
  2dup > if swap then
  drop ;

: min ( n1 n2 -- n )
  2dup <
  \ 3 1 3dup   ->  3 1 3 1
  \ 3 1 3 1 <  ->  3 1 0
  \ 3 1 0
  \ seeking something that uses 0 to keep the 1
  \ - - maybe?
  \ ans ?
  \ 3 1 0 or -> 3 1
  \ 3 1 nip -> 1

  \ 1 3 -1 or  ->  1 -1
;

: min
  2dup > 1+ pick nip nip ;

: min
  2dup > 1+ roll nip ;

\ : min
\   \ 3 1 -- 1 3
\   \ adds the information, which one is greater
\   2dup >
\   \ 3 1 -1 -- 1 3 0
\   \ `and` sets the greater value to 0 and keeps the smaller
\   \ value, because of different result of > (-1 or 0)
\   and
\   \ 3 1 -- 1 0
\   \ tuck stores the smaller number, if it is on top of the
\   \ stack, at the bottom of the stack. If the smaller number
\   \ is not at the top of the stack, then it stores a 0 at
\   \ the bottom of the stack.
\   tuck
\   \ After `tuck` we still have either the smaller number on
\   \ top of the stack or a zero, because of `and` with false
\   \ (0). However, we also have a "backup" of the smaller
\   \ number at the bottom of the stack, so that we can work
\   \ with the top element, without losing the minimum number.

\   \ 1 3 1 -- 0 1 0

\   \ 0= will determin, whether we have had the smaller number
\   \ on top, or a 0 and give 0 or -1 as a result. This makes
\   \ the actual distinction between the smaller number and 0,
\   \ as it outputs a -1 for input 0 and a 0 for any other
\   \ input:

\   \ If there is a 0, we get a -1, which is all bits set to
\   \ 1. We only got a 0 on the stack, when the bigger number
\   \ was on top of the stack initially.

\   \ If there is a non-zero value, we get a 0, which is all
\   \ bits set to 0. We only got a 0, if the smaller number
\   \ was initially on top of the stack. (OR ZERO AS A NUMBER!
\   \ MISTAKE!)
\   0=
\   \ 1 3 0 -- 0 1 -1
\   and
\   \ 1 0 -- 0 1
\   or
\   \ 1 -- 1
\ ;


: min ( a b - x )
  \ adds the information, which one is greater
  2dup <
  tuck
  0=
  and
  -rot and or ;


\ Test cases:
2 0 min .s .
0 2 min .s .
0 -1 min .s .
-1 0 min .s .
3 1 min .s .
1 3 min .s .
